package de.dailab.graphworld.bean;

import de.dailab.graphworld.bean.memory.NodeInfo;
import de.dailab.graphworld.ontology.Node;
import de.dailab.graphworld.world.ExtendedGraphWorldAgentBean;
import de.dailab.jiactng.agentcore.action.Action;
import de.dailab.jiactng.agentcore.action.ActionResult;
import de.dailab.jiactng.agentcore.ontology.IActionDescription;
import java.io.Serializable;

/**
 * An abstract implementation of a {@link TeamMember} that occurs in the graph
 * world. Scouts and carriers are implementations of this class, broker not.
 *
 * @author Kseniya
 */
public abstract class BeanPhysical extends TeamMember {

    private IActionDescription actionInit;

    @Override
    public void doStart() {
        super.doStart();
        actionInit = thisAgent.searchAction(new Action(ExtendedGraphWorldAgentBean.ACTION_INIT_TEAM_POSITION));
    }

    @Override
    public void execute() {
        if (!isInitialisedInWorld()) {
            initialiseInWorld();
        }
    }

    /**
     * Per default, the team member is not placed in world at the first
     * execute(...) call, so an appropriate action must be invoked to assign
     * this bean to a team.
     *
     * @return
     */
    protected boolean isInitialisedInWorld() {
        NodeInfo storedPosition = memory.read(new NodeInfo(null));
        return storedPosition != null;
    }

    private void initialiseInWorld() {
        this.invoke(actionInit, new Serializable[]{getTeamName()}, this);
    }

    @Override
    public void receiveResult(ActionResult result) {
        if (result.getFailure() == null
                && ExtendedGraphWorldAgentBean.ACTION_INIT_TEAM_POSITION.equals(result.getAction().getName())) {
            Node curr = (Node) result.getResults()[0];
            memory.write(new NodeInfo(curr));
        }
        super.receiveResult(result);
    }
}
